using com.tc.assistance.protocol.entity;
using System.Collections.Generic;
using com.tc.assistance.entity.device;
using com.tc.assistance.parser;
using System.Xml;
using System.IO;
using com.tc.assistance.utils;

namespace com.tc.assistance.engine
{

    abstract public class AbstractController : ServerService, ProtocolMessageProvider, ProtocolMessageSender, RegisterListener
    {
        static public AbstractController instance;
        List<ServerListener> slisteners = new List<ServerListener>();
        List<RegisterListener> rlisteners = new List<RegisterListener>();
        List<ProtocolMessageListener> plisteners = new List<ProtocolMessageListener>();
        public void addServerListener(ServerListener l)
        {
            slisteners.Add(l);
        }
        SipService sipService;
        DetailedRelation relation;
        public AbstractController()
        {


            sipService = new sip.SipServiceImpl();
            sipService.setRegisterListener(this);
            sipService.setMessageListener(this);

        }

        abstract public GeneralDevice getDevice();

        private string mydefination()
        {

            Stream stream = new MemoryStream();
            StreamReader sr = new StreamReader(stream);
            XmlTextWriter serializer = new XmlTextWriter(stream, null);

            serializer.WriteStartDocument();
            ProtocolStreamer.streamDevice(serializer, getDevice());
            serializer.WriteEndDocument();
            
            string all = sr.ReadToEnd();
            return all;
        }
        /* (non-Javadoc)
         * @see com.tc.assistance.controller.SwitchDeviceControllerInterface#defination()
         */
        public void defination()
        {
            string xml = mydefination();
            HttpServer.getInstance().writeDevice(xml);
            foreach (ServerListener l in slisteners)
                l.onDefinationUploaded();

        }
        /* (non-Javadoc)
         * @see com.tc.assistance.controller.SwitchDeviceControllerInterface#relationship()
         */
        public void relationship(){
		relation = HttpServer.getInstance().readRelation(getDevice().getId());
		devices.Clear();
			foreach(Relationship r in this.relation.outd){
				string deviceId = r.getToId();
				GeneralDevice device = HttpServer.getInstance().readDefination(deviceId);
				devices.Add(deviceId, device);
				r.setDevice(device);
				
			}
			foreach(ServerListener l in slisteners)
				l.onRelationDownloaded(relation, devices);

	}
        public DetailedRelation getRelation()
        {
            return relation;
        }
        public Dictionary<string, GeneralDevice> getDevices()
        {
            return devices;
        }
        Dictionary<string, GeneralDevice> devices = new Dictionary<string, GeneralDevice>();
        public void start()
        {


                sipService.start();

           
        }

        public void onMessage(string from, string msg) {

		ProtocolMessage mo = ProtocolParser.parseProtocolMessage(msg);
		mo.from = from;
		mo.to = getDevice().getId();
		foreach(ProtocolMessageListener l in plisteners)
			l.onMessage(mo);		
		
	}
        public void sendMessage(ProtocolMessage report)
        {
            string xml = ProtocolStreamer.stream(report);
            string to = "SIP:" + report.to + "@" + "nist.gov"; // modified

            this.sipService.message(to, xml);
        }
        public void addMessageListener(ProtocolMessageListener l)
        {
            plisteners.Add(l);

        }
        public void removeMessageListener(ProtocolMessageListener l)
        {
            plisteners.Remove(l);

        }
        public void addRegisterListener(RegisterListener l)
        {
            rlisteners.Add(l);

        }
        public ProtocolMessageSender getSender()
        {
            // TODO Auto-generated method stub
            return this;
        }
        public void message(string to, string m)
        {

            to = "SIP:" + to + "@" + "nist.gov"; // modified

            this.sipService.message(to, m);

        }

        public void registerStarted() {
		foreach(RegisterListener l in rlisteners)
			l.registerStarted();
		
	}

        public void registerSuccess()
        {
            foreach (RegisterListener l in rlisteners)
                l.registerSuccess();

        }

    }
}
